/* vim: set expandtab shiftwidth=4: -*- mode: c++; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil -*-
EasyForms
An easy-to-use program for completing scanned documents.
Copyright (C) 2006-2007 Wesley Crossman
Email: wesley@crossmans.net

You can redistribute and/or modify this software under the terms of the GNU
General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this
program; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA */

#include "FormsDocument.h"
#include "FormsDocumentScene.h"
#include "FormsWindow.h"
#include <QImageReader>
#include <QFontComboBox>
#include <QLabel>
#include <QSpinBox>
#include <QPrintDialog>
#include <QPrinter>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>

QString FormsWindow::selectedDir = QDir::home().absolutePath();

FormsWindow::FormsWindow() {
    scene = NULL;
    document = NULL;
    setupUi(this);
    insertToolBarBreak(tbrSettings);
    tbrSettings->addWidget(new QLabel(tr("Main Font: "), this));

    cmbFont = new QFontComboBox(this);
    //cmbFont->setFontFilters(QFontComboBox::ScalableFonts);
    cmbFont->setCurrentFont(QFont(QFont().defaultFamily(), 12));
    FormsTextItem::defaultFont = cmbFont->currentFont();
    tbrSettings->addWidget(cmbFont);

    spnFont = new QSpinBox(this);
    spnFont->setRange(4, 128);
    spnFont->setValue(12);
    tbrSettings->addWidget(spnFont);

    tbrSettings->addSeparator();
    tbrSettings->addWidget(new QLabel(tr("CheckBox: "), this));

    spnCheck = new QSpinBox(this);
    spnCheck->setSuffix("%");
    spnCheck->setRange(1, 1000);
    spnCheck->setSingleStep(10);
    spnCheck->setValue(100);
    tbrSettings->addWidget(spnCheck);

    modes = new QActionGroup(this);
    items = new QActionGroup(this);
    
    aAddLine->setCheckable(true);
    aRemoveLine->setCheckable(true);
    aEdit->setCheckable(true);
    modes->addAction(aAddLine);
    modes->addAction(aRemoveLine);
    modes->addAction(aEdit);
    aEdit->setChecked(true);
    aCheckBox->setCheckable(true);
    aTextBox->setCheckable(true);
    items->addAction(aCheckBox);
    items->addAction(aTextBox);
    aTextBox->setChecked(true);

    connect(aNew, SIGNAL(triggered()), SLOT(newTriggered()));
    connect(aOpen, SIGNAL(triggered()), SLOT(openTriggered()));
    connect(aSaveAs, SIGNAL(triggered()), SLOT(saveAsTriggered()));
    connect(cmbFont, SIGNAL(currentFontChanged(const QFont &)), SLOT(fontChanged()));
    connect(spnFont, SIGNAL(valueChanged(int)), SLOT(fontChanged()));
    connect(spnCheck, SIGNAL(valueChanged(int)), SLOT(checkSizeChanged()));
    connect(aPrint, SIGNAL(triggered()), SLOT(printTriggered()));
    connect(aFormsIn, SIGNAL(triggered()), SLOT(zoomIn()));
    connect(aFormsOut, SIGNAL(triggered()), SLOT(zoomOut()));
    connect(aForms100, SIGNAL(triggered()), SLOT(zoom100()));
    connect(aAddLine, SIGNAL(triggered()), SLOT(setAddLine()));
    connect(aRemoveLine, SIGNAL(triggered()), SLOT(setRemoveLine()));
    connect(aEdit, SIGNAL(triggered()), SLOT(setEdit()));
    connect(aAddPage, SIGNAL(triggered()), SLOT(addPageTriggered()));
    connect(aDeletePage, SIGNAL(triggered()), SLOT(deletePageTriggered()));
    connect(items, SIGNAL(triggered(QAction *)), SLOT(itemSelectionChanged()));

    updateUi();
}

void FormsWindow::updateUi() {
    bool pageIsOpen = scene, docIsOpen = document;
    bool inLineEditMode = pageIsOpen && aAddLine->isChecked();
    aSave->setEnabled(docIsOpen);
    aSaveAs->setEnabled(docIsOpen);
    aPrint->setEnabled(pageIsOpen);
    aErase->setEnabled(pageIsOpen);
    aFormsIn->setEnabled(pageIsOpen);
    aFormsOut->setEnabled(pageIsOpen);
    aForms100->setEnabled(pageIsOpen);
    modes->setEnabled(pageIsOpen);
    items->setEnabled(inLineEditMode);
    aFirstPage->setEnabled(pageIsOpen && !document->atStart());
    aPreviousPage->setEnabled(pageIsOpen && !document->atStart());
    aNextPage->setEnabled(pageIsOpen && !document->atEnd());
    aLastPage->setEnabled(pageIsOpen && !document->atEnd());
    aAddPage->setEnabled(docIsOpen);
    aDeletePage->setEnabled(docIsOpen);
    cmbFont->setEnabled(inLineEditMode);
    spnFont->setEnabled(inLineEditMode);
    spnCheck->setEnabled(inLineEditMode);

}

void FormsWindow::pageIndexChanged() {
    scene = document->getPage();
    grvDocument->setScene(scene);
}

void FormsWindow::newTriggered() {
    delete document;
    scene = NULL;
    document = new FormsDocument(this);
    connect(document, SIGNAL(countChanged(int)), SLOT(updateUi()));
    connect(document, SIGNAL(selectedPageChanged(int, QString)), SLOT(pageIndexChanged()));
    aEdit->setChecked(true);
    setEdit();
}

void FormsWindow::openTriggered() {
    QString selected = QFileDialog::getOpenFileName(this, tr("Open..."), selectedDir, tr("Forms (*.zip)"));
    if (!selected.isNull()) {
        selectedDir = QFileInfo(selected).absolutePath();
        delete document;
        document = new FormsDocument(selected, this); //XXX error checking
        aEdit->setChecked(true);
        setEdit();
    }
}

void FormsWindow::saveAsTriggered() {
    /*static QString selectedDir = QDir::home().absolutePath();
    QString selected = QFileDialog::getSaveFileName(this, tr("Save As..."), selectedDir, tr("Forms (*.zip)"));
    if (!selected.isNull()) {
        selectedDir = QFileInfo(selected).absolutePath();
        QuaZip zip(selected);
        if (!zip.open(QuaZip::mdCreate)) {
            QMessageBox::warning(this, tr("Error Saving File"),
                    tr("The file could not be created. (Error 10)"));
            return;
        }
        QuaZipFile outFile(&zip);
        if (outFile.open(QIODevice::WriteOnly,
                    QuaZipNewInfo("pages.xml", "pages.xml"))) {
            QTextStream outStream(&outFile);
            scene->write(outStream);
        } else {
            QMessageBox::warning(this, tr("Error Saving File"),
                    tr("The file could not be created. (Error 11)"));
            return;
        }
        outFile.close();
        if (outFile.open(QIODevice::WriteOnly,
                    QuaZipNewInfo("page1.png", "page1.png"))) {
            scene->writeImage(&outFile);
        } else {
            QMessageBox::warning(this, tr("Error Saving File"),
                    tr("The file could not be created. (Error 12)"));
            return;
        }
        outFile.close();
    }*/
}

void FormsWindow::printTriggered() {
    /*QPrinter printer(QPrinter::HighResolution);
    QPrintDialog printDialog(&printer, this);
    if (printDialog.exec() == QDialog::Accepted) {
        QPainter painter(&printer);
        painter.setRenderHints(QPainter::TextAntialiasing|QPainter::Antialiasing);
        FormsItem::setMode(FormsItem::Print, scene);
        items->setEnabled(false);
        scene->render(&painter);
        setEdit();
    }*/
}

void FormsWindow::addPageTriggered() {
    QStringList imageNameFilters;
    foreach (QByteArray format, QImageReader::supportedImageFormats()) {
        imageNameFilters.append(QString("*.") + QString(format).toLower());
    }
    QString selected = QFileDialog::getOpenFileName(this, tr("Open..."), selectedDir, tr("Images (%1);;All Files (*.*)").arg(imageNameFilters.join(" ")));
    if (!selected.isNull()) {
        selectedDir = QFileInfo(selected).absolutePath();
        document->addPage(selected, "");
    }
}

void FormsWindow::deletePageTriggered() {
}

void FormsWindow::zoomIn() {
    grvDocument->scale(1.2, 1.2);
    updateHintsForZoom();
    updateUi();
}

void FormsWindow::zoomOut() {
    grvDocument->scale(1/1.2, 1/1.2);
    updateHintsForZoom();
    updateUi();
}

void FormsWindow::zoom100() {
    grvDocument->resetMatrix();
    updateHintsForZoom();
    updateUi();
}

void FormsWindow::updateHintsForZoom() {
    qreal zoom = grvDocument->matrix().m22();
    if (zoom > 0.999 && zoom < 1.001) {
        grvDocument->setRenderHint(QPainter::Antialiasing, false);
    } else {
        grvDocument->setRenderHint(QPainter::Antialiasing, true);
    }
}

void FormsWindow::setAddLine() {
    //FormsItem::setMode(FormsItem::Design, scene);
    updateUi();
}

void FormsWindow::setRemoveLine() {
    //FormsItem::setMode(FormsItem::Delete, scene);
    updateUi();
}

void FormsWindow::setEdit() {
    //FormsItem::setMode(FormsItem::Edit, scene);
    updateUi();
}

void FormsWindow::fontChanged() {
    /*QFont font(cmbFont->currentFont());
    font.setPointSize(spnFont->value());
    FormsTextItem::defaultFont = font;
    foreach (QGraphicsItem *item, scene->items()) {
        FormsTextItem *textItem = dynamic_cast < FormsTextItem * >(item);
        if (textItem) {
            textItem->setFont(font);
            textItem->updateForNewSize();
        }
    }*/
}

void FormsWindow::checkSizeChanged() {
    /*foreach (QGraphicsItem *item, scene->items()) {
        FormsCheckBox *checkBox = dynamic_cast < FormsCheckBox * >(item);
        FormsCheckBox::defaultSize = spnCheck->value()/100.0;
        if (checkBox) {
            checkBox->setScale(spnCheck->value()/100.0);
        }
    }*/
}

void FormsWindow::itemSelectionChanged() {
    if (aCheckBox->isChecked()) {
        FormsDocumentScene::selected = FormsDocumentScene::CheckBox;
    } else if (aTextBox->isChecked()) {
        FormsDocumentScene::selected = FormsDocumentScene::TextBox;
    }
}

